using UnityEditor;
using UnityEngine;
using System.Collections;

public class lwUVLightmapAuthoringTools : EditorWindow
{
	/*********************************** File Log Manager ********************************************/
	public System.IO.StreamWriter m_sr;
	private const string sLofFileName = "LightmappingTools_log.txt";

	/*********************************** Scene Creation variables ********************************************/
	public string m_sScenePathName = "";
	public string m_sSceneName = "";
	public bool m_bIsSceneSave = false;
	private bool m_bUseCuurentScene = false;
	private bool m_bIsFirstTimeOpen = true;
	private bool m_bIsOrderCreate = false;
	private bool m_bGenerateUV = false;
	private int m_nbTagScene = 0;

	/*********************************** Windows Editor Variables ********************************************/
	public int toolbarInt = 0;
	private Vector2 scrollLoads0;
	private Vector2 scrollLoads1;
	private Vector2 scrollLoads2;
	private Vector2 scrollLoads3;
	private Vector2 scrollLoads4;
	private string[] mainContent = null;

	/************************************* UV Generation variables *********************************/
	private int nSizeLightMapArray = 0;
	private int nSizeLightMapArray2 = 0;
	public GameObject[] LightMapUvMeshsToGenerate;
	public string[] TagToLightMapToGenerate;
	public bool GenerateUV = false;
	private int m_nInitPosTagTop = 73;
	private int m_nInitPosTagleft = 130;
	private int m_nCoefSpaceBetweenTag = 19;
	private string m_sErrorStringUV = "";

	/************************************* Normals Generation variable *********************************/
	private  ModelImporterTangentSpaceMode m_normalUserChoice = ModelImporterTangentSpaceMode.None;
	private bool otherSettings;
	private bool m_bDisableNormals = false;

	/************************************* Lightmap Generation variable *********************************/
//	public LightmapSceneData[] lightmapDataArray;
	public GameObject DirectionnalLightArray;
	public bool BakingLightmap = false;
	public float m_nScaleInLightmap = 1;
	private bool m_bIsGenerateNotBegin = false;

	public LightmapsMode m_lightmapMode;
	public LightmapBakeQuality m_quality;

	/********************************* Export to Resources folder ********************************/
	private int m_nCurrentTrackIdxGenerate = 1;
	private string m_sPathFolderLight = "";
	private string m_sParentFolderName = "";
	private string m_sSuffixe = "track_";
	private bool MoveToResources = false;
	private string m_sPreviousPathLightMap = "";
	private string m_CurrentPathWriting = "";

	/********************************* Final Generation ********************************/
	private int m_nFinalState = 0;
	private bool m_bIsFullAuto = false;

	/*********************************** Clean Scene **********************************/
	private bool m_isCleanScene = false;

	[MenuItem ("Tools/LWS/UV and Lightmap")]
	static void ShowWindow ()
	{
         
		EditorWindow window;
      
		window = (EditorWindow)EditorWindow.GetWindowWithRect (typeof(lwUVLightmapAuthoringTools), new Rect (50, 50, 500, 300), false, "Lightmap UV Generation & baking");
		window.autoRepaintOnSceneChange = true;
		window.Show ();
	}

	//Update to avoid GUI errors -_-... thanks Unity for that opti
	void Update()
	{
		if( m_bIsOrderCreate )
		{
			m_bIsOrderCreate = false;
			CreateOpenScene();
		}

		if( m_isCleanScene )
		{
			m_isCleanScene = false;
			CleanScene();
		}

		if( m_bIsGenerateNotBegin )
		{
			m_bIsGenerateNotBegin = false;
			ChooseFinalState();
		}
		
		if( m_bGenerateUV )
		{
			m_bGenerateUV = false;
			GenerateLightmapUVArray ( LightMapUvMeshsToGenerate );
		}

		if( m_bDisableNormals )
		{
			m_bDisableNormals = false;
			DisableNormalTangent( LightMapUvMeshsToGenerate );
		}
	}

	//Here we create all the interface !
	void OnGUI ()
	{
		EditorGUILayout.BeginVertical (GUI.skin.GetStyle ("Box"));
		if (mainContent == null)
		{
			mainContent = new string[5];
			
			string sTab0 = "Init Scene";
			mainContent [0] = sTab0;

			string sTab1 = "Generate UV";
			mainContent [1] = sTab1;

			string sTab2 = "Lghtmps Set. & Bake";
			mainContent [2] = sTab2;

			string sTab3 = "Lightmps Managemt";
			mainContent [3] = sTab3;

			string sTab4 = "Gen. UV & Lghtmps";
			mainContent [4] = sTab4;
		}

		int nNewToolBarInt = GUILayout.SelectionGrid (toolbarInt, mainContent, 5, GUILayout.Height (20));
		EditorGUILayout.EndVertical ();
		
		if( nNewToolBarInt != toolbarInt )
		{
			Repaint();
			toolbarInt = nNewToolBarInt;
		}

		/** This part is the creation of the UV lightmaps for each meshs you wanna put in da scene to build lightmap **/
		if (toolbarInt == 0) {
			#region SceneCreation
			scrollLoads4 = EditorGUILayout.BeginScrollView (scrollLoads4, GUILayout.Height (Screen.height - 100));
				EditorGUILayout.BeginVertical (GUI.skin.GetStyle ("Box"));

					if( m_bIsFirstTimeOpen )
					{
						GetPathToSceneFolder();
						m_bIsFirstTimeOpen = false;
					}

					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Scene path ");
						m_sScenePathName = EditorGUILayout.TextField ( m_sScenePathName );
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Scene name");
						m_sSceneName = EditorGUILayout.TextField ( m_sSceneName );
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Save scene ");
						m_bIsSceneSave = EditorGUILayout.Toggle ( m_bIsSceneSave );
						if ( m_bIsSceneSave )
							m_bUseCuurentScene = false;
					EditorGUILayout.EndHorizontal ();

					EditorGUILayout.Space();
					EditorGUILayout.BeginHorizontal();
						EditorGUILayout.PrefixLabel("Use Current scene ");
						m_bUseCuurentScene = EditorGUILayout.Toggle( m_bUseCuurentScene );
						if ( m_bUseCuurentScene )
							m_bIsSceneSave = false;
					EditorGUILayout.EndHorizontal();

					EditorGUILayout.BeginHorizontal();
						if (GUILayout.Button ("Create your new scene"))
						{
							m_bIsOrderCreate = true;
						}
					EditorGUILayout.EndHorizontal();
				EditorGUILayout.EndVertical();
			EditorGUILayout.EndScrollView ();
			#endregion //Create New Scene
		}
		else if (toolbarInt == 1)
		{
			#region GenerationUV

			scrollLoads0 = GUILayout.BeginScrollView (scrollLoads0, GUILayout.Height (Screen.height - 100));
				EditorGUILayout.BeginVertical (GUI.skin.GetStyle ("Box"));

					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
							EditorGUILayout.PrefixLabel ("Generate lightmap UV");
							GenerateUV = EditorGUILayout.Toggle (GenerateUV);
							EditorGUILayout.PrefixLabel ("Others Settings");
							otherSettings = EditorGUILayout.Toggle (otherSettings);
					EditorGUILayout.EndHorizontal ();

//					if( otherSettings )
//					{
//						ModelImporterTangentSpaceMode blib;
//						EditorGUILayout.BeginHorizontal();
//							ModelImporterTangentSpaceMode = EditorGUILayout.EnumPopup( "Normal mod : ", ModelImporterTangentSpaceMode );
//						EditorGUILayout.EndHorizontal();
//					}

					if (nSizeLightMapArray <= 0)
					{
						nSizeLightMapArray = 0;
						nSizeLightMapArray2 = 0;
					}

					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						nSizeLightMapArray2 = EditorGUILayout.IntField ("Nb prefab to generate :", nSizeLightMapArray);
					EditorGUILayout.EndHorizontal ();
		
					if (nSizeLightMapArray2 == 0)
						LightMapUvMeshsToGenerate = new GameObject[0];
					else if (nSizeLightMapArray2 != nSizeLightMapArray)
					{
						int difference = nSizeLightMapArray2 - nSizeLightMapArray;
	
						if (difference < 0 && Mathf.Abs (difference) >= LightMapUvMeshsToGenerate.Length)
						{
							System.Array.Resize<GameObject> (ref LightMapUvMeshsToGenerate, 0);
							if( m_bIsFullAuto )
								System.Array.Resize<string> (ref TagToLightMapToGenerate, 0);
						}
						else
						{
							System.Array.Resize<GameObject> (ref LightMapUvMeshsToGenerate, LightMapUvMeshsToGenerate.Length + difference);
							if( m_bIsFullAuto )
								System.Array.Resize<string> (ref TagToLightMapToGenerate, TagToLightMapToGenerate.Length + difference);
						}
						nSizeLightMapArray = nSizeLightMapArray2;
					}
	
					EditorGUILayout.Space ();
					for (int i = 0; i < LightMapUvMeshsToGenerate.Length; i++)
					{
						EditorGUILayout.BeginHorizontal();
							LightMapUvMeshsToGenerate [i] = (GameObject)EditorGUILayout.ObjectField ("\tObject", LightMapUvMeshsToGenerate [i], typeof(GameObject), true);
							if( m_bIsFullAuto )
								TagToLightMapToGenerate[i] = EditorGUI.TagField( new Rect( m_nInitPosTagleft, m_nInitPosTagTop + i * m_nCoefSpaceBetweenTag, 10, 10 ), TagToLightMapToGenerate[i] );
						EditorGUILayout.EndHorizontal();
					}
	
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
					if (GUILayout.Button ("Generate Lightmap UV"))
					{
						m_bGenerateUV = true;
					}
					EditorGUILayout.EndHorizontal ();

					EditorGUILayout.BeginHorizontal ();
					if (GUILayout.Button ("Disable normals"))
					{
						m_bDisableNormals = true;
					}
					EditorGUILayout.EndHorizontal ();

					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.LabelField (m_sErrorStringUV);
					EditorGUILayout.EndHorizontal ();
				EditorGUILayout.EndVertical ();
			GUILayout.EndScrollView ();

			#endregion //Generation UV management
		}
		else if (toolbarInt == 2)
		{
            # region Settings implementation

			scrollLoads1 = GUILayout.BeginScrollView (scrollLoads1, GUILayout.Height (Screen.height - 100));
				EditorGUILayout.Space ();

				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Mode");
					LightmapSettings.lightmapsMode = (LightmapsMode)EditorGUILayout.EnumPopup (LightmapSettings.lightmapsMode);
				EditorGUILayout.EndHorizontal ();

				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Quality");
					LightmapEditorSettings.quality = (LightmapBakeQuality)EditorGUILayout.EnumPopup (LightmapEditorSettings.quality);
				EditorGUILayout.EndHorizontal ();
	
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Bounces");
					LightmapEditorSettings.bounces = EditorGUILayout.IntPopup (LightmapEditorSettings.bounces, new string[] { "0", "1", "2", "3", "4" }, new int[] { 0, 1, 2, 3, 4 });
				EditorGUILayout.EndHorizontal ();
	
				if (LightmapEditorSettings.bounces > 0) {
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("SkyLight Color");
						LightmapEditorSettings.skyLightColor = EditorGUILayout.ColorField (LightmapEditorSettings.skyLightColor);
					EditorGUILayout.EndHorizontal ();
	
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						GUILayout.Label ("SkyLight Intensity");
						LightmapEditorSettings.skyLightIntensity = EditorGUILayout.FloatField (LightmapEditorSettings.skyLightIntensity);
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Bounce Boost");
						LightmapEditorSettings.bounceBoost = EditorGUILayout.Slider (LightmapEditorSettings.bounceBoost, 0, 4);
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Bounce Intensity");
						LightmapEditorSettings.bounceIntensity = EditorGUILayout.Slider (LightmapEditorSettings.bounceIntensity, 0, 5);
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Final Gather Rays");
						LightmapEditorSettings.finalGatherRays = EditorGUILayout.IntField (LightmapEditorSettings.finalGatherRays);
					EditorGUILayout.EndHorizontal ();

					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Contrast Threshold");
						LightmapEditorSettings.finalGatherContrastThreshold = EditorGUILayout.Slider (LightmapEditorSettings.finalGatherContrastThreshold, 0, 0.5f);
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Interpolation");
						LightmapEditorSettings.finalGatherGradientThreshold = EditorGUILayout.Slider (LightmapEditorSettings.finalGatherGradientThreshold, 0, 1);
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Interpolation Points");
						LightmapEditorSettings.finalGatherInterpolationPoints = EditorGUILayout.IntSlider (LightmapEditorSettings.finalGatherInterpolationPoints, 15, 30);
					EditorGUILayout.EndHorizontal ();
				}
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Ambient Occlusion");
					LightmapEditorSettings.aoAmount = EditorGUILayout.Slider (LightmapEditorSettings.aoAmount, 0, 1);
				EditorGUILayout.EndHorizontal ();
		
				if (LightmapEditorSettings.aoAmount > 0) {
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Max Distance");
						LightmapEditorSettings.aoMaxDistance = EditorGUILayout.FloatField (LightmapEditorSettings.aoMaxDistance);
					EditorGUILayout.EndHorizontal ();
		
					EditorGUILayout.Space ();
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.PrefixLabel ("Contrast");
						LightmapEditorSettings.aoContrast = EditorGUILayout.Slider (LightmapEditorSettings.aoContrast, 0, 2);
					EditorGUILayout.EndHorizontal ();
				}

				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Lock Atlas");
					LightmapEditorSettings.lockAtlas = EditorGUILayout.Toggle (LightmapEditorSettings.lockAtlas);
				EditorGUILayout.EndHorizontal ();
		
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Resolution");
					LightmapEditorSettings.resolution = EditorGUILayout.FloatField (LightmapEditorSettings.resolution);
					EditorGUILayout.LabelField ("Texels per world unity", "");
				EditorGUILayout.EndHorizontal ();
	
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.LabelField ("Last texel resolution used : ", LightmapEditorSettings.lastUsedResolution.ToString ());
				EditorGUILayout.EndHorizontal ();
	
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Texture Compression");
					LightmapEditorSettings.textureCompression = EditorGUILayout.Toggle (LightmapEditorSettings.textureCompression);
				EditorGUILayout.EndHorizontal ();
		
				EditorGUILayout.Space ();
				GUILayout.TextArea ("Set the following field to the targeted size of your baked lightmap.\n reducing the size will increase the number of lightmaps and eventually different objects will have different lightmap, increasing the size will reduce the number of lightmaps and eventually different objects will have single lightmap");
				EditorGUILayout.BeginHorizontal ();
					GUILayout.Label ("Max Atlas Width\\Height");
					LightmapEditorSettings.maxAtlasWidth = EditorGUILayout.IntPopup (LightmapEditorSettings.maxAtlasWidth, new string[] { "32", "64", "128", "256", "512","1024","2048","4096" }, new int[] { 32, 64, 128, 256, 512,1024,2048,4096});
					LightmapEditorSettings.maxAtlasHeight = LightmapEditorSettings.maxAtlasWidth;
				EditorGUILayout.EndHorizontal ();
				EditorGUILayout.Space ();
	
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Scale in Lightmap ");
					m_nScaleInLightmap = EditorGUILayout.FloatField (m_nScaleInLightmap);
				EditorGUILayout.EndHorizontal ();
				EditorGUILayout.Space ();
	
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Lightmap baking");
					BakingLightmap = EditorGUILayout.Toggle (BakingLightmap);
				EditorGUILayout.EndHorizontal ();

				EditorGUILayout.Space ();
				DirectionnalLightArray = (GameObject)EditorGUILayout.ObjectField ("\tDirectionnal Light", DirectionnalLightArray, typeof(GameObject), true);

				EditorGUILayout.Space();
				EditorGUILayout.BeginHorizontal ();
					if (GUILayout.Button ("Bake Lightmap"))
					{
						InitScene ();
						BakingScene ();
					}

					if (GUILayout.Button ("Clear Lightmap"))
						Lightmapping.Clear();
				EditorGUILayout.EndHorizontal ();
			GUILayout.EndScrollView ();
			#endregion //Settings Config
		} else if (toolbarInt == 3)
		{
			#region ResourceManagement
			scrollLoads2 = EditorGUILayout.BeginScrollView (scrollLoads2, GUILayout.Height (Screen.height - 100));
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Move to Resources folder");
					MoveToResources = EditorGUILayout.Toggle (MoveToResources);
				EditorGUILayout.EndHorizontal ();

				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Parent folder in Resources folder : ");
					m_sParentFolderName = EditorGUILayout.TextField ( m_sParentFolderName );
				EditorGUILayout.EndHorizontal ();

				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Folder : ");
					m_sPathFolderLight = EditorGUILayout.TextField( m_sPathFolderLight );
					if ( m_sPathFolderLight != string.Empty )
						m_sSuffixe = m_sPathFolderLight;
					else
						m_sSuffixe = "track_";
						
				EditorGUILayout.EndHorizontal ();
	
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					if (GUILayout.Button ("Move to Resources"))
						MoveLightmapToResources ();
				EditorGUILayout.EndHorizontal ();
			EditorGUILayout.EndScrollView ();
			#endregion //ResourceManagement
		}
		else if (toolbarInt == 4)
		{
			#region FinalGeneration
			string ButName = "";
			scrollLoads3 = EditorGUILayout.BeginScrollView (scrollLoads3, GUILayout.Height (Screen.height - 100));
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.PrefixLabel ("Bake all scene auto ");
					m_bIsFullAuto = EditorGUILayout.Toggle( m_bIsFullAuto );
				EditorGUILayout.EndHorizontal ();

				if( m_bIsFullAuto )
				{
					EditorGUILayout.BeginHorizontal ();
						EditorGUILayout.LabelField ("You activate full automatic mod, please config the tag in second tab");
					EditorGUILayout.EndHorizontal ();
				}
					
				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
	
				if (GenerateUV) {
					ButName = "UV only";
					m_nFinalState = 1;
					if (BakingLightmap) {
						ButName = "UV & Bake";
						m_nFinalState = 3;
						if (MoveToResources) {
							ButName = " UV & Bake & Move To Resources Folder ";
							m_nFinalState = 4;
						}
					}
				} else {
					if (BakingLightmap) {
						ButName = "Bake only";
						m_nFinalState = 2;
						if (MoveToResources) {
							ButName = " UV & Bake & Move To Resources Folder ";
							m_nFinalState = 4;
						}
					} else {
						ButName = "Nothing to do";
						m_nFinalState = 0;
					}
				}
	
				if (GUILayout.Button (ButName))
				{
					CreateStreamWriter( sLofFileName );
					m_bIsGenerateNotBegin = true;
				}
				EditorGUILayout.EndHorizontal ();

				EditorGUILayout.Space ();
				EditorGUILayout.BeginHorizontal ();
					EditorGUILayout.LabelField ( ButName );
				EditorGUILayout.EndHorizontal ();
			EditorGUILayout.EndScrollView ();
			#endregion //Final Generation
		}
			
		EditorGUILayout.BeginHorizontal ();
			if (GUILayout.Button ("Clean scene"))
			{
				m_isCleanScene = true;
			}
		EditorGUILayout.EndHorizontal ();
		
		if ( m_bIsFullAuto )
		{
			EditorGUILayout.BeginHorizontal ();
				GUILayout.Label ( "Delete manually your tag if don't needed after tools over" );
			EditorGUILayout.EndHorizontal ();
		}
		else if( TagToLightMapToGenerate == null && m_bIsFullAuto )
		{
			EditorGUILayout.BeginHorizontal ();
				GUILayout.Label ( "Need tag to do something ; Exit" );
			EditorGUILayout.EndHorizontal ();
		}
	}

	//Function to genereate the lightmap uv of each prefab and children
	private void GenerateLightmapUVArray (GameObject[] gameObject)
	{
		CreateStreamWriter( sLofFileName );
		m_sr.WriteLine("================= COMPUTE LIGHTMAP UV... ===================");
		//Check if the array is empty, if yes USER GTFO !
		if (nSizeLightMapArray == 0 || LightMapUvMeshsToGenerate [0] == null)
			m_sErrorStringUV = "Need at least 1 mesh in the array above !";
		//Otherwise loop on each prefab and check them wit hthe recursive function
		else
		{
			for (int i = 0; i < gameObject.Length; i++)
				GenerateLightMapUV2 (gameObject [i]);
        }
		m_sr.WriteLine("================= COMPUTE LIGHTMAP UV OVER ===================");
	}

	private void DisableNormalTangent (GameObject[] gameObject)
	{
		CreateStreamWriter( sLofFileName );
		m_sr.WriteLine("================= COMPUTE NORMALS MESH... ===================");

		//Check if the array is empty, if yes USER GTFO !
		if (nSizeLightMapArray == 0 || LightMapUvMeshsToGenerate [0] == null)
			m_sErrorStringUV = "Need at least 1 mesh in the array above !";
		//Otherwise loop on each prefab and check them wit hthe recursive function
		else
		{
			for (int i = 0; i < gameObject.Length; i++)
				DisableNormalTangentRecur (gameObject [i]);
        }
		m_sr.WriteLine("================= COMPUTE NORMALS MESH OVER ===================");
	}

	private void DisableNormalTangentRecur( GameObject gameObject )
	{
		bool bCanIterate = true;
		MeshFilter meshFilter = gameObject.GetComponent<MeshFilter> ();
		MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer> ();

		//Check if my mesh have and filter and a renderer so it's the final
		if (meshFilter != null && meshRenderer != null)
		{
//			Debug.Log("mesh : " + meshFilter);
//			Debug.Log ("mesh shared : " + meshFilter.sharedMesh);
			m_sr.WriteLine("mesh : " + meshFilter);
			m_sr.WriteLine("mesh shared : " + meshFilter.sharedMesh);
		
			//Take the mesh of the file
			Mesh meshLightmapped = Application.isPlaying ? meshFilter.mesh : meshFilter.sharedMesh;

			//Take the file's path and put it in a string
			string path = AssetDatabase.GetAssetPath (meshLightmapped);
//			Debug.Log ("Model path : " + path);
			m_sr.WriteLine("Model path : " + path);

			string extensionPath = System.IO.Path.GetExtension (path);

//			Debug.Log ("extension path : " + extensionPath);
			m_sr.WriteLine ("extension path : " + extensionPath);

			if ( extensionPath.Equals (".fbx") )
			{
				bCanIterate = false;
//				Debug.Log("Le chemin : " + AssetImporter.GetAtPath( path ) );
				m_sr.WriteLine("Le chemin : " + AssetImporter.GetAtPath( path ) );

				//Define a modelImporter to modify its importing settings
				ModelImporter model = AssetImporter.GetAtPath (path) as ModelImporter;

				//Put the generateSecondaryUV field to true and GenerateUVSet for the mesh
				if ( m_normalUserChoice != model.normalImportMode )
				{
//					Debug.Log("uv ? : " + model.generateSecondaryUV );
					m_sr.WriteLine( "Normal importer : " + m_normalUserChoice );
					model.normalImportMode = m_normalUserChoice;
				}
            }
			else
            {
				//Define a modelImporter to modify its importing settings
				ModelImporter model = AssetImporter.GetAtPath (path) as ModelImporter;

				//Put the generateSecondaryUV field to true and GenerateUVSet for the mesh
				if ( m_normalUserChoice != model.normalImportMode )
				{
					m_sr.WriteLine( "Normal importer : " + m_normalUserChoice );
					model.normalImportMode = m_normalUserChoice;
				}
            }

			m_sr.WriteLine( "------------------------------------" );

			//Update the mesh setting in editor
			AssetDatabase.SaveAssets();
			AssetDatabase.ImportAsset( path );
			AssetDatabase.ImportAsset( path, ImportAssetOptions.ForceSynchronousImport) ;
		}

		if( bCanIterate )
		{
			//Iterate on the children if they have something to render too AND if they are .ASSET
	        foreach (Transform t in gameObject.transform)
	        	GenerateLightMapUV2 (t.gameObject);
		}
	}

	//Recursive function switch all uv2 of mesh to true
	private void GenerateLightMapUV2 (GameObject gameObject)
	{
		bool bCanIterate = true;
		MeshFilter meshFilter = gameObject.GetComponent<MeshFilter> ();
		MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer> ();

		//Check if my mesh have and filter and a renderer so it's the final
		if (meshFilter != null && meshRenderer != null)
		{
//			Debug.Log("mesh : " + meshFilter);
//			Debug.Log ("mesh shared : " + meshFilter.sharedMesh);
			m_sr.WriteLine("mesh : " + meshFilter);
			m_sr.WriteLine("mesh shared : " + meshFilter.sharedMesh);
		
			//Take the mesh of the file
			Mesh meshLightmapped = Application.isPlaying ? meshFilter.mesh : meshFilter.sharedMesh;

			//Take the file's path and put it in a string
			string path = AssetDatabase.GetAssetPath (meshLightmapped);
//			Debug.Log ("Model path : " + path);
			m_sr.WriteLine("Model path : " + path);

			string extensionPath = System.IO.Path.GetExtension (path);

//			Debug.Log ("extension path : " + extensionPath);
			m_sr.WriteLine ("extension path : " + extensionPath);

			if ( extensionPath.Equals (".fbx") )
			{
				bCanIterate = false;
//				Debug.Log("Le chemin : " + AssetImporter.GetAtPath( path ) );
				m_sr.WriteLine("Le chemin : " + AssetImporter.GetAtPath( path ) );

				//Define a modelImporter to modify its importing settings
				ModelImporter model = AssetImporter.GetAtPath (path) as ModelImporter;

				//Put the generateSecondaryUV field to true and GenerateUVSet for the mesh
				if (!model.generateSecondaryUV)
				{
//					Debug.Log("uv ? : " + model.generateSecondaryUV );
					m_sr.WriteLine("Create UV : " + !model.generateSecondaryUV );

					model.generateSecondaryUV = true;
					Unwrapping.GenerateSecondaryUVSet (meshLightmapped);
				}
            }
			else
            {
				Unwrapping.GenerateSecondaryUVSet (meshLightmapped);
            }

			m_sr.WriteLine( "------------------------------------" );

			//Update the mesh setting in editor
			AssetDatabase.SaveAssets();
			AssetDatabase.ImportAsset( path );
			AssetDatabase.ImportAsset( path, ImportAssetOptions.ForceSynchronousImport) ;
		}

		if( bCanIterate )
		{
			//Iterate on the children if they have something to render too AND if they are .ASSET
	        foreach (Transform t in gameObject.transform)
	        	GenerateLightMapUV2 (t.gameObject);
		}
	}

	//Complete process of baking a scene and move lightmap in resources
	private void GenerateLightmapFinal ()
	{
		string[] sTempTagArray = new string[1];
		bool bIsInArray = false;
		m_nbTagScene = 0;

		//If user don't use the current scene to bake we must create new one to do all his mess
		if ( !m_bUseCuurentScene )
		{
//			Debug.Log("Create the scene where we gonna work...");
			m_sr.WriteLine("Create the scene where we gonna work...");
			CreateOpenScene();
//			Debug.Log("Scene created !");
			m_sr.WriteLine("Scene created !");
		}

		//If he choose to bake multiple scene
		if( m_bIsFullAuto )
		{
			//If the temp tag array have just a size of one, we push the first tag find in it
			if( sTempTagArray.Length == 1 )
			{
				sTempTagArray[0] = TagToLightMapToGenerate[0];
				//Increment the indice tag system
				m_nbTagScene++;
			}

			//then for each tag in the Tag Array from the editor window we must iterate
			for(int i = 1 ; i < TagToLightMapToGenerate.Length ; i++ )
			{
				//Then we check with the tag in Unique User Tag Array
				foreach( string sTag in sTempTagArray )
				{
					//If the tag already exists, say it to the bool
					if( TagToLightMapToGenerate[i].Equals( sTag ))
						bIsInArray = true;
				}

				//If previous bool is set to false so the tag doesn't exists
				if( !bIsInArray )
				{
					//Resize our tag array to add the new one
					System.Array.Resize<string> (ref sTempTagArray, sTempTagArray.Length + 1);
					//Add the tag to the array
					sTempTagArray[m_nbTagScene] = TagToLightMapToGenerate[i];
					//Increment the number of tag in the array
					m_nbTagScene++;
				}
			}
		}

		//If don't need to iterate around multiple scene simple bake for one level
		if( !m_bIsFullAuto )
		{
			Debug.Log ("Init the scene with all elements...");
			InitScene ();
			Debug.Log ("Scene Init OK");

			Debug.Log ("Start baking the scene...");
			BakingScene ();
			Debug.Log ("Scene bake OK");

			Debug.Log("Start moving element to your folder choice...");
			MoveLightmapToResources();
			Debug.Log("Move over !");

//			Debug.Log("Start cleaning scene...");
//			CleanScene();
//			Debug.Log("Clean over");
		}
		//Otherwise must use the tag system
		else
		{
			Debug.Log("Size to iterate : " + m_nbTagScene );
			for( int i = 0 ; i < m_nbTagScene ; i++ )
			{
				Debug.Log ("Init the scene with all elements...");
				InitScene ();
				Debug.Log ("Scene Init OK");

				Debug.Log ("Start baking the scene...");
				BakingScene ();
				Debug.Log ("Scene bake OK");

				Debug.Log("Start moving element to your folder choice...");
				MoveLightmapToResources();
				Debug.Log("Move over !");

				Debug.Log("Start cleaning scene...");
				CleanScene();
				Debug.Log("Clean over");
			}
		}
	}

	//Create or open a scene if exists
	private void CreateOpenScene ()
	{
		string tempVarSceneName = "";
		if( !m_bUseCuurentScene )
		{
			//If the user don't give a path to the scene folder, must find it alone Ã©_Ã¨ or create it :D
			if( m_sScenePathName == string.Empty )
			{
				//So take the datapath and add it a "Scenes" folder and taht it
				m_sScenePathName = Application.dataPath + "/Scenes/";
	
				//If don't exist create it
				if( !System.IO.Directory.Exists( m_sScenePathName ))
					System.IO.Directory.CreateDirectory( m_sScenePathName );
			}
	
			//If the scene name is empty so create a default scene to bake
			if( m_sSceneName == string.Empty )
				tempVarSceneName = "DaBakingScene";
			else
				tempVarSceneName = m_sSceneName;
	
			char lastCharString = m_sScenePathName [m_sScenePathName.Length - 1];
			string sFullPathAndName = "";
	
			//Check if last m_sScenePathName is / to don't add it to create the scene file
			if ( lastCharString.Equals("/") )
				sFullPathAndName = m_sScenePathName + tempVarSceneName + ".unity";
			else
				sFullPathAndName = m_sScenePathName + "/" + tempVarSceneName + ".unity";
	
	//		Debug.Log("Full path : " + sFullPathAndName );
	
			if ( !EditorApplication.OpenScene( sFullPathAndName ) )
			{
				//Here we create the new scene
				EditorApplication.NewScene ();
	
				//If user tick save scene, we save the scene for him
				if (m_bIsSceneSave)
				{
					EditorApplication.SaveScene (sFullPathAndName);
					Debug.Log("Save the current scene !");
				}
				//Otherwise, maybe he just forget so we display a confirmation window before to do something to be sure
				else
				{
					Debug.Log( EditorApplication.SaveScene (sFullPathAndName) );
					EditorApplication.SaveAssets();
					Debug.Log ("Save the current scene with user agreement !");
				}
			}
			else
			{
				Debug.Log("Open current scene !");
			}
		}
		else
		{
			EditorApplication.SaveScene( EditorApplication.currentScene );
		}
	}

	//Init our scene view with all game object
	private void InitScene ()
	{
		CreateStreamWriter( sLofFileName );
		
		string sTagToUse = "";
		bool bIsFirstTimePassThrough = true;
		GameObject[] m_goToBakeArray;
		int nTempArraySize = 0;
		
		m_sr.WriteLine("===================== SCENE INITIALIZATION BEGIN =========================");
		m_sr.WriteLine("  ------------------ START WORKING ON GAME OBJECT ---------------------");
		//If we are in simple mod don't use the tag system
		if( !m_bIsFullAuto )
		{
			//Init all the gameobject from our window in the scene (Transform must be set in the prefab before import them in editor window )
			foreach (GameObject go in LightMapUvMeshsToGenerate)
//				Instantiate (go);
				PrefabUtility.InstantiatePrefab( go );
		}
		//In this case, use tag system to bake more than 1 scene
		else
		{
			nTempArraySize = 0;
			m_goToBakeArray = new GameObject[1];
//			Debug.Log("Tag size array : " + TagToLightMapToGenerate.Length );
			m_sr.WriteLine("Tag size array : " + TagToLightMapToGenerate.Length );

			//Iterate on all my tag in my array display in the editor window
			for(int i = 0 ; i < TagToLightMapToGenerate.Length ; i++)
			{
				//If the tag is not null and it's not the first time I see it
				if( TagToLightMapToGenerate[i] != null && !bIsFirstTimePassThrough )
				{
					//I check with each other TagToLightMapToGenerate value if someone match with mine
					if( sTagToUse.Equals( TagToLightMapToGenerate[i] ) )
					{
						//So I resize my array of one cause I find one more
						System.Array.Resize<GameObject> (ref m_goToBakeArray, m_goToBakeArray.Length + 1);
						//I increment my temp indices
						nTempArraySize++;
//						Debug.Log("Le tableau a pour valeur ceci : " + LightMapUvMeshsToGenerate[i] + " a l'indice suivante alors hein bis : " + i );
						m_sr.WriteLine("Le tableau a pour valeur ceci : " + LightMapUvMeshsToGenerate[i] + " a l'indice suivante alors hein bis : " + i );
//						Debug.Log("Je prends l'object avec le tag suivant alors me fait pas chier je pique et c'est tout merouer bis : " + sTagToUse );

						//I push the assets corresponding to the current equal tag in my temporary array to bake the scene
						m_goToBakeArray[nTempArraySize] = LightMapUvMeshsToGenerate[i];

						//Then I put the 2 field to null to not check them again and again and again...
						TagToLightMapToGenerate[i] = null;
						LightMapUvMeshsToGenerate[i] = null;
					}
				}

				if( TagToLightMapToGenerate[i] != null && bIsFirstTimePassThrough )
				{
//					Debug.Log("Le tableau a pour valeur ceci : " + LightMapUvMeshsToGenerate[i] + " a l'indice suivante alors hein : " + i );
//					Debug.Log("Je prends l'object avec le tag suivant alors me fait pas chier je pique et c'est tout merouer : " + sTagToUse );
					sTagToUse = TagToLightMapToGenerate[i];
					bIsFirstTimePassThrough = false;
					m_goToBakeArray[nTempArraySize] = LightMapUvMeshsToGenerate[i];
					TagToLightMapToGenerate[i] = null;
					LightMapUvMeshsToGenerate[i] = null;
				}
			}

//			Debug.Log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
//			Debug.Log(" Array size : " + m_goToBakeArray.Length );
//			for(int i = 0 ; i < m_goToBakeArray.Length; i++ )
//				Debug.Log( "Name object : " + m_goToBakeArray[i].name );
//			Debug.Log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");


			foreach (GameObject go in m_goToBakeArray)
//				Instantiate (go);
				PrefabUtility.InstantiatePrefab( go );
		}
		m_sr.WriteLine("  ------------------ END WORKING ON GAME OBJECT ---------------------");
		m_sr.WriteLine("  ------------------ START INIT LIGHT OBJECT ---------------------");
		//Think to do the same thing for the lights cause just 1 light possible here so associate a tag to a light
		Instantiate ( DirectionnalLightArray );
		m_sr.WriteLine("  ------------------ END INIT LIGHT OBJECT ---------------------");
		m_sr.WriteLine("===================== SCENE INITIALIZATION OVER =========================");
	}

	//Force all game object in our scene as static
	private void StaticAllTheScene ()
	{
		//Iterate on all our gameobject in the scene and put them as static
		GameObject[] goList = new GameObject[GameObject.FindSceneObjectsOfType (typeof(GameObject)).Length];

		//Take all gameobject type and put them in da list
		goList = (GameObject[])GameObject.FindSceneObjectsOfType (typeof(GameObject));
		
//		Debug.Log("size nb go scene : " + goList.Length );
		m_sr.WriteLine("size nb go scene : " + goList.Length );

//		Debug.Log ("Real start of static & scale in lightmap...");
		m_sr.WriteLine(" ==========> Real start of static & scale in lightmap...");
		for (int i = 0; i < goList.Length; i++)
		{
//			Debug.Log("Liste de game object : " + goList[i].name );
			m_sr.WriteLine("Current game object to test : " + goList[i].name );

//			Debug.Log("====================================================");
//			Debug.Log("Is Static : " + goList[i].isStatic + " My object name : " + goList[i].name );
//			Debug.Log("His parent : " + goList[i].transform.parent + " - have a light ? " + goList[i].GetComponent<Light>());
//			Debug.Log("====================================================");

			//Put all gameObject static field to true
			if ( goList [i].GetComponent<Light> () == null )
			{
				goList[i].isStatic = true;
				
//				Debug.Log("is static : " + goList[i].isStatic );
				m_sr.WriteLine("is static : " + goList[i].isStatic );
				
//				if (goList [i].transform.parent == null)
					ScaleInLightmapAll (goList [i]);
			}
			EditorUtility.SetDirty ( goList[i] );
			string path = AssetDatabase.GetAssetPath(goList[i]);
			AssetDatabase.ImportAsset(path);
			AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport);
//			Debug.Log("====================================================");
//			Debug.Log("Is Static : " + goList[i].isStatic + " My object name : " + goList[i].name );
//			Debug.Log("His parent : " + goList[i].transform.parent + " - have a light ? " + goList[i].GetComponent<Light>());
//			Debug.Log("====================================================");
		}
		
		EditorApplication.SaveAssets ();
		AssetDatabase.SaveAssets ();

		ReplaceOldPrefWithNew();
			
//		Debug.Log ("Static & scale in lightmap over");
	}

	//Modify all scale of our object to a new one
	private void ScaleInLightmapAll (GameObject go)
	{		
		//Check if he got a renderer
		if (go.renderer != null)
		{
			//Serialized my object to allow to modify every property in it
			SerializedObject so = new SerializedObject (go.GetComponent<Renderer> ());
			SerializedProperty goScaleProperty = so.FindProperty("m_ScaleInLightmap");

			m_sr.WriteLine ("--- Scale value before : " + so.FindProperty ("m_ScaleInLightmap").floatValue + " ---");

			//Find the property and modify them
			goScaleProperty.floatValue = m_nScaleInLightmap;

			//Apply the modified properties
			so.ApplyModifiedProperties (); //Send true but this is working ? oO

//			Debug.Log ("Scale value after : " + so.FindProperty ("m_ScaleInLightmap").floatValue);
			m_sr.WriteLine ("--- Scale value after : " + so.FindProperty ("m_ScaleInLightmap").floatValue + " ---");

//			string sAssetPath = AssetDatabase.GetAssetPath( go );
//			AssetDatabase.ImportAsset( sAssetPath );
		}
	}

	//Bake all the scene in async mod if it's the last thing to do or sync if it's the complete execution
	private void BakingScene ()
	{
		m_bIsGenerateNotBegin = false;
		//Check all the mesh in the scene and put them static
//		Debug.Log ("Convert all mesh to static...");
		m_sr.WriteLine ("=============== Convertion Scale & Static BEGIN ==============");
		StaticAllTheScene ();
//		Debug.Log ("Convertion over.");
//		Debug.Log ("=============================");
		m_sr.WriteLine ("=============== Convertion Scale & Static OVER ==============");

//		Debug.Log ("Baking...");
//		Debug.Log ("Current tooltip : " + toolbarInt.ToString ());
		m_sr.WriteLine ("Baking...");
		m_sr.WriteLine ("Current tooltip : " + toolbarInt.ToString ());

		//Bake the current scene in synchronous mod to block all the rest and stop the application
		if (toolbarInt == 2)
			Lightmapping.Bake ();
		else if (toolbarInt == 4)
			Lightmapping.Bake ();
//		Debug.Log ("Baking over");
//		Debug.Log ("===================================");
		m_sr.WriteLine("Baking over");
		m_sr.WriteLine("===================================");
				
		EditorApplication.SaveAssets ();
		AssetDatabase.SaveAssets ();

		//Iterate on all the list to replace the old prefab
		ReplaceOldPrefWithNew ();
	}

	//clean the scene
	private void CleanScene ()
	{
		//Unlaod all the assets that are not more usefull for us
		Resources.UnloadUnusedAssets ();

		//Get the current scene path to reload it after
		string sPathSceneToDelete = EditorApplication.currentScene;

		//Relaod the current scene in its initial state
		EditorApplication.OpenScene (sPathSceneToDelete);

	}

	//Move the lightmap to the folder choose by the user in a default one otherwise
	private void MoveLightmapToResources ()
	{
		CreateStreamWriter( sLofFileName );
		
		string pathToFolder = "Assets/Resources/";
		string sFullPathAndName2 = "";

		//If parent folder name exists create a Root in Resources folder
		if (m_sParentFolderName != string.Empty)
		{
			Debug.Log("Parent folder name : " + m_sParentFolderName );

			pathToFolder = pathToFolder + m_sParentFolderName;

			if (!System.IO.Directory.Exists ( pathToFolder ))
			{
				System.IO.Directory.CreateDirectory ( pathToFolder );
				Debug.Log ("Folder parent doesn't exist create it !");
			}
			else
				Debug.Log ("Folder parent exists do nothing !");
			pathToFolder = pathToFolder + "/";
		}

		//Automatically generate the folder for a track (level) for the user in the Resources folder
		if ( !System.IO.Directory.Exists ( pathToFolder + m_sSuffixe + "0" + m_nCurrentTrackIdxGenerate ) )
		{
			//If we change of folder and previously already iterate reinitiliaze the iterator value
			if (pathToFolder + m_sSuffixe != m_sPreviousPathLightMap && m_nCurrentTrackIdxGenerate > 1)
				m_nCurrentTrackIdxGenerate = 1;
			
			//If the directory doesn't exists create it and add 0 if we are inferior to 10
			if (m_nCurrentTrackIdxGenerate < 10) {
				m_CurrentPathWriting = pathToFolder + m_sSuffixe + "0" + m_nCurrentTrackIdxGenerate + "/";
				System.IO.Directory.CreateDirectory (pathToFolder + m_sSuffixe + "0" + m_nCurrentTrackIdxGenerate );
			}
			else
			{
				m_CurrentPathWriting = pathToFolder + m_sSuffixe + m_nCurrentTrackIdxGenerate + "/";
				System.IO.Directory.CreateDirectory( pathToFolder + m_sSuffixe + m_nCurrentTrackIdxGenerate );
			}
		}

		//This keep the previous folder path of lightmap save to compare with next above
		m_sPreviousPathLightMap = pathToFolder + m_sSuffixe;

		//Increment the iterator
		m_nCurrentTrackIdxGenerate++;

		//If user choose to keep the current scene to bake take its name
		if( m_bUseCuurentScene )
		{
			m_sSceneName = EditorApplication.currentScene;
			m_sSceneName = System.IO.Path.GetFileNameWithoutExtension( m_sSceneName );			
		}

		//Get the last char of the path
		char lastCharString = m_sScenePathName [m_sScenePathName.Length - 1];

		//If it's a "/" so I can stick the scene name with scene path
		if ( lastCharString.Equals("/") )
		{
			sFullPathAndName2 = m_sScenePathName + m_sSceneName;
			Debug.Log("path name : " + sFullPathAndName2 );
		}
		//If not I add the "/" manually
		else
		{
			sFullPathAndName2 = m_sScenePathName + "/" + m_sSceneName;
			Debug.Log("path name : " + sFullPathAndName2 );
		}

		//When I'm sure the exit folder exists, I push the lightmap in it
		foreach( string sFilePath in System.IO.Directory.GetFiles( sFullPathAndName2, "*.exr" ) )
		{
			Debug.Log("Move this file : " + sFilePath  + " -> " + m_CurrentPathWriting + " with name : " + sFilePath );
			m_sr.WriteLine( "Move this file : " + sFilePath  + " -> " + m_CurrentPathWriting + " with name : " + sFilePath );
			string sFileName = System.IO.Path.GetFileName( sFilePath );
			
			//Move the lightmap in the right folder
			System.IO.File.Move( sFilePath, m_CurrentPathWriting + sFileName );
			
			//Then delete its old meta files
			System.IO.File.Delete( AssetDatabase.GetTextMetaDataPathFromAssetPath( sFilePath ) );
		}
//		ReplaceOldPrefWithNew ();
	}

	//Get the path to the first folder containing a ".unity" file
	public void GetPathToSceneFolder()
     { 
          string[] files;
           
          // Stack of folders: 
          Stack stack = new Stack(); 
 
          // Add root directory: 
          stack.Push( Application.dataPath );
 
          // Continue while there are folders to process 
          while (stack.Count > 0) 
          { 
               // Get top folder: 
               string dir = (string)stack.Pop();
 
               try
               {
               		// Get a list of all scene in this folder:
                    files = System.IO.Directory.GetFiles(dir, "*.unity");

                    // Process all prefabs:
                   if( files.Length > 0 )
						m_sScenePathName = System.IO.Path.GetDirectoryName( files[0] );

                    // Add all subfolders in this folder:
                    foreach (string dn in System.IO.Directory.GetDirectories(dir))
                    { 
                         stack.Push(dn); 
                    } 
               } 
               catch 
               { 
                    // Error 
                    Debug.LogError("Could not access folder: \"" + dir + "\"");
               } 
          } 
     }

	//Function to know the final state to display correct function with final button
	private void ChooseFinalState()
	{
		m_bIsGenerateNotBegin = false;
		if (m_nFinalState == 1)
		{
			GenerateLightmapUVArray (LightMapUvMeshsToGenerate);
		}
		else if (m_nFinalState == 2)
		{
			BakingScene ();
		}
		else if (m_nFinalState == 3)
		{
			m_sr.WriteLine("=============== BEGINNING OF THIRD STATE ===================");
			GenerateLightmapUVArray (LightMapUvMeshsToGenerate);
			InitScene ();
			BakingScene ();
			VerifyPrefabModify();
			m_sr.WriteLine("=============== ENDING OF THIRD STATE ===================");
			m_sr.WriteLine("=============== STREAMWRITER CLOSED ===================");
			m_sr.Close();
		}
		else if (m_nFinalState == 4)
		{
			m_sr.WriteLine("=============== BEGINNING OF FOURTH STATE ===================");
			GenerateLightmapUVArray (LightMapUvMeshsToGenerate);
			GenerateLightmapFinal ();
			m_sr.WriteLine("=============== ENDING OF FOURTH STATE ===================");
			m_sr.WriteLine("=============== STREAMWRITER CLOSED ===================");
			m_sr.Close();
		}
	}
	
	//Replace the previous prefab with the new version of the scene instance
	private void ReplaceOldPrefWithNew( )
	{
		//Iterate on all our gameobject in the scene and put them as static
		GameObject[] goList = new GameObject[GameObject.FindSceneObjectsOfType (typeof(GameObject)).Length];

		//Take all gameobject type and put them in da list
		goList = (GameObject[])GameObject.FindSceneObjectsOfType (typeof(GameObject));
		
		for (int i = 0; i < LightMapUvMeshsToGenerate.Length; i++)
		{
			string stringTrim = "";
			for (int j = 0; j < goList.Length; j++)
			{
				if ( goList [j].transform.parent == null )
				{
//					Debug.Log("prefab name : " + goList[j].name );
//					Debug.Log("Prefab parent : " +  PrefabUtility.GetPrefabParent( goList[j] ) );
					m_sr.WriteLine("prefab name : " + goList[j].name );
					m_sr.WriteLine("Prefab parent : " +  PrefabUtility.GetPrefabParent( goList[j] ) );
				
					string clone = "(Clone)";
					stringTrim = goList [j].name.Trim (clone.ToCharArray ());
					string pathPrefab = AssetDatabase.GetAssetPath (LightMapUvMeshsToGenerate [i]);
					pathPrefab = System.IO.Path.GetFileNameWithoutExtension ( pathPrefab );
					
					if ( stringTrim.Equals ( pathPrefab ) )
					{
//						Debug.Log("Replace prefab : " + LightMapUvMeshsToGenerate [i] );
						m_sr.WriteLine("Replace prefab : " + LightMapUvMeshsToGenerate [i] );
						PrefabUtility.ReplacePrefab( goList [j], PrefabUtility.GetPrefabObject ( LightMapUvMeshsToGenerate [i] ) );
					}
					AssetDatabase.SaveAssets();
					EditorApplication.SaveAssets();
					
					AssetDatabase.ImportAsset( pathPrefab );
					AssetDatabase.ImportAsset( pathPrefab, ImportAssetOptions.ForceSynchronousImport) ;
				}
			}
		}
	}

	void CreateStreamWriter( string path )
	{
		if( m_sr == null )
		{
			m_sr = new System.IO.StreamWriter( path, false );
			m_sr.WriteLine ("==================== LOG LIGHTMAPPING TOOLS ==================");
		}
	}
	
	void VerifyPrefabModify( )
	{
		m_sr.WriteLine("==================== CHECK FILES INTEGRITY SCENE/PROJECT ==================");
		//Iterate on all our gameobject in the scene and put them as static
		GameObject[] goList = new GameObject[GameObject.FindSceneObjectsOfType(typeof(GameObject)).Length];

		//Take all gameobject type and put them in da list
		goList = (GameObject[])GameObject.FindSceneObjectsOfType(typeof(GameObject));
				
		//Check all the asset in scene are modify
		foreach( GameObject go in goList )
		{
//			string sRealPrefabPath = AssetDatabase.GetAssetPath( PrefabUtility.GetPrefabParent( go ) );
//			GameObject goRealPrefabObject = AssetDatabase.LoadAssetAtPath( sRealPrefabPath, typeof(GameObject) ) as GameObject;
			//Check if he got a renderer
			if (go.renderer != null)
			{
				//Serialized my object to allow to check these properties
				m_sr.WriteLine("-------------------------- ASSET IN SCENE ----------------------------");
				m_sr.WriteLine("--- Gameobject name : " + go.name + "---");
				SerializedObject so = new SerializedObject (go.GetComponent<Renderer> ());
				m_sr.WriteLine("--- Lightmap idx value : " + so.FindProperty("m_LightmapIndex").intValue + " ---");
				//m_sr.WriteLine("--- Lightmap tilling & offset value : " + so.FindProperty("m_LightmapTilingOffset").rectValue + " ---");
				m_sr.WriteLine("------------------------------------------------------");
				
				//Serialized my object to check these properties
//				m_sr.WriteLine("-------------------------- ASSET IN PROJECT ----------------------------");
//				m_sr.WriteLine("--- Gameobject name : " + goRealPrefabObject.name + "---");
//				SerializedObject soRealPrefab = new SerializedObject(goRealPrefabObject.GetComponent<Renderer>());
//				m_sr.WriteLine("--- Lightmap idx value : " + soRealPrefab.FindProperty("m_LightmapIndex").intValue + " ---");
//				//m_sr.WriteLine("--- Lightmap tilling & offset value : " + soRealPrefab.FindProperty("m_LightmapTilingOffset").enumValueIndex + " ---");
//				m_sr.WriteLine("------------------------------------------------------");
			}
		}
	}
}